// Stephen Toub
// stoub@microsoft.com

using System;
using System.IO;
using System.Text;
using System.Collections;
using System.Runtime.InteropServices;
using System.Collections.Generic;

namespace WMVConvert.Metadata
{
	/// <summary>Metadata editor for ASF files, including WMA, WMV, and DVR-MS files.</summary>
	public abstract class EditorBase : IDictionary<WMAttribute,object>, IDisposable
	{
		/// <summary>Path to the file whose metadata is being edited.</summary>
		private string path;

		/// <summary>Initialize the editor.</summary>
		protected EditorBase(string path)
		{
			if (path == null) throw new ArgumentNullException("path");
			this.path = path;
		}

		/// <summary>Releases all of the resources for the editor.</summary>
		public void Dispose()
		{
			Dispose(true);
			GC.SuppressFinalize(this);
		}

		/// <summary>Releases all of the resources for the editor.</summary>
		/// <param name="disposing">Whether the object is currently being disposed (rather than finalized).</param>
		protected virtual void Dispose(bool disposing) {}

		/// <summary>Releases all of the resources for the editor.</summary>
		~EditorBase() { Dispose(false); }

		/// <summary>Gets the path to the file being edited.</summary>
		public string Path { get { return path; } }

		#region IDictionary<string,object> Members

		public abstract object this[WMAttribute key] { get; set; }

		public abstract void Add(WMAttribute key, object value);

		public abstract bool ContainsKey(WMAttribute key);

		public abstract ICollection<WMAttribute> Keys
		{
			get;
		}

		public abstract bool Remove(WMAttribute key);

		public abstract bool TryGetValue(WMAttribute key, out object value);

		public ICollection<object> Values
		{
			get
			{
				List<object> values = new List<object>();
				foreach (WMAttribute key in Keys)
				{
					object item = null;
					if ( TryGetValue(key,out item))
					{
						values.Add(item);
					}
				}
				return values;
			}
		}

		#endregion

		#region ICollection<KeyValuePair<WMAttribute,object>> Members

		public abstract void Add(KeyValuePair<WMAttribute, object> item);

		public abstract void Clear();

		public abstract bool Contains(KeyValuePair<WMAttribute, object> item);

		public void CopyTo(KeyValuePair<WMAttribute, object>[] array, int arrayIndex)
		{
			foreach (WMAttribute key in Keys)
			{
				array[arrayIndex++] = new KeyValuePair<WMAttribute, object>(key, this[key]);
			}
		}

		public abstract int Count { get; }

		public bool IsReadOnly
		{
			get { return false; }
		}

		public abstract bool Remove(KeyValuePair<WMAttribute, object> item);

		#endregion

		#region IEnumerable<KeyValuePair<WMAttribute,object>> Members

		public IEnumerator<KeyValuePair<WMAttribute, object>> GetEnumerator()
		{
			throw new Exception("The method or operation is not implemented.");
		}

		#endregion

		#region IEnumerable Members

		IEnumerator IEnumerable.GetEnumerator()
		{
			return (IEnumerator)this.GetEnumerator();
		}

		#endregion
	}
}